from typing import List
from common.enum.strategy_group_enum import StrategyGroup
from common.enum.strategy_type_enum import StrategyType
from dto.strategy_info import StrategyInfoMetadata
from dto.strategy_assessment import RiskAssessment
from dto.strategy_info import StrategyInfoMetadata
from dto.strategy_stock_day import StrategyStockDay
from service.strategy.base_strategy import BaseStrategy


class FifteenDaysPeakDropStrategy(BaseStrategy):
    """
    关注策略：分析某个股票在15天内是否存在一个最高点，且股价已跌去20%以上。
    另外，分析最新交易日的前5天内，股票波动上下不超过10%。
    """

    def analyze(self, trade_info_list: List[StrategyStockDay]) -> RiskAssessment:
        """
        分析股票在过去15天内的价格波动情况。
        """
        node_point = 0
        description = ""

        # 确保至少有15天的交易数据
        if len(trade_info_list) >= 15:
            # 获取过去15天的价格数据
            last_15_days = trade_info_list[-15:]

            # 找到过去15天的最高点
            max_price = max([day.close for day in last_15_days])
            max_day = next(day for day in last_15_days if day.close == max_price)

            # 当前股价是否已经跌去20%以上
            current_price = trade_info_list[-1].close
            if current_price <= max_price * 0.8:
                node_point += 2
                description += f"股票从最高点下跌了20%以上 {max_price}. "

        # 检查最新交易日的前5天是否股价波动不超过10%
        if len(trade_info_list) >= 6:
            recent_5_days = trade_info_list[-6:-1]

            # 计算波动幅度（最高价 - 最低价）/ 最低价
            price_range = max([day.high for day in recent_5_days]) - min(
                [day.low for day in recent_5_days]
            )
            min_price = min([day.low for day in recent_5_days])
            if price_range / min_price <= 0.1:
                node_point += 3
                description += (
                    "过去5天内股价波动小于10%. "
                )

        return RiskAssessment(
            stock_code=trade_info_list[0].stock_code,
            description=description,
            config=self.strategyConfig(),
            node_point=node_point,
        )

    def strategyConfig(self) -> StrategyInfoMetadata:
        """
        返回策略的配置
        """
        return StrategyInfoMetadata(
            strategy_code="fifteen_days_peak_drop",
            strategy_name="15天内最高点跌幅超过20% 且最近5天波动不超过10%",
            strategy_group=StrategyGroup.ATTENTION,  # 关注型策略
            strategy_type=StrategyType.VOLUME,  # 根据成交量类型
            analysis_day=15,
            strategy_level=2,
        )
